﻿#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace GameToolkit
{
    public partial class CullingCamera
    {

        public static Color[] colors = new Color[] { Color.green,
            Color.Lerp(Color.green, Color.blue, 0.5f),
            Color.Lerp(Color.blue, Color.red, 0.25f),
            Color.red,
            Color.gray };

        private void OnValidate()
        {
            if (isActiveAndEnabled)
            {
                InitCapacity(m_CullingCapacity);
                if (mCullingGroup != null)
                {
                    if (m_DistanceLv.w > m_DistanceLv.z
                        && m_DistanceLv.z > m_DistanceLv.y
                        && m_DistanceLv.y > m_DistanceLv.x)
                    {
                        mDistanceLvs[0] = m_DistanceLv.x;
                        mDistanceLvs[1] = m_DistanceLv.y;
                        mDistanceLvs[2] = m_DistanceLv.z;
                        mDistanceLvs[3] = m_DistanceLv.w;
                        mCullingGroup.SetBoundingDistances(mDistanceLvs);
                        mCullingGroup.SetBoundingSpheres(mCullingSpheres);
                        mCullingGroup.SetBoundingSphereCount(mCullLength);
                    }
                }
            }
            DebugCamera.ForceReset = true;
        }

        internal ICollection<IPreCullAction> PreCullActions { get { return mPreCulls; } }

        //private void OnDrawGizmos()
        //{
        //    Gizmos.DrawIcon(transform.position, "Cull Icon.png", false);
        //}

        List<CullingState> drawing = new List<CullingState>();

        public void ValidateCullingBounds(Camera sceneCam, Ray ray, bool raycast, float validateSize)
        {
            drawing.Clear();
            var layers = DebugCamera.debugLayers;
            if (DebugCamera.debugCullDistance > 0 && layers != 0)
            {
                var right = sceneCam.transform.right;
                var states = GetEnumerator(DebugCamera.debugCullDistance);
                Vector3 p;
                if (raycast)
                    DebugCamera.BeginRaycast(ray.origin);
                while (states != null && states.MoveNext())
                {
                    var st = states.Current;
                    if ((layers & (1 << st.bounds.Layer)) == 0)
                        continue;
                    var draw = st.bounds as ICullingBoundsDebug;
                    if (draw != null)
                    {
                        var cullbounds = st.bounds.Bounding;
                        var sp = sceneCam.WorldToScreenPoint(cullbounds.position);
                        var sp2 = sceneCam.WorldToScreenPoint(cullbounds.position + right * cullbounds.radius) - sp;
                        if (sp.x < -sp2.x || sp.x > sp2.x + sceneCam.pixelWidth || sp.y < -sp2.y || sp.y > sp2.y + sceneCam.pixelHeight)
                            continue;
                        if (raycast && draw.Raycast(ray, out p))
                        {
                            st.type = GizmoType.Pickable;
                            DebugCamera.Raycast(st, p);
                            drawing.Add(st);
                        }
                        else if (Vector3.SqrMagnitude(cullbounds.position - ray.origin) > cullbounds.radius * cullbounds.radius &&
                            st.bounds.Bounding.radius > HandleUtility.GetHandleSize(st.bounds.Bounding.position) * validateSize)
                        {
                            st.type = 0;
                            drawing.Add(st);
                        }
                    }

                    //draw.DrawGizmos(st);
                    //else
                    //    DrawGizmo(st);
                }
                if (raycast)
                    DebugCamera.EndRaycast();
            }
        }

        private void OnDrawGizmosSelected()
        {
            for (int i = 0; i < drawing.Count; i++)
            {
                var st = drawing[i];
                if (DebugCamera.SelectedBounds == st.bounds)
                    st.type |= GizmoType.Selected;
                ((ICullingBoundsDebug)st.bounds).DrawGizmos(st);

            }
        }

    }
}
#endif